﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Resources;
using System.Windows.Forms;
using AppRPG.PhysObject;
using KolloreRPG.Properties;

namespace KolloreRPG
{
    public class Editor
    {
        private List<PhysObject> _accessPhysicalObjects;
        public int BeginShowAccessPhysicalObjects;

        private List<PhysObject> _makedPhysicalObjects;

        public PhysObject CurrentPhysicalObject;
        private int indexCurrentPhysicalObject;

        public PhysObject ChoosePhysicalObject;
        public PhysObject MovingPhysicalObject;
        public PhysObject LastMovingGameObject;

        public Point _oldPositionMouse;

        private Point oldPositionMovingGameObject;
        private Point positonCurrentGameObject;

        private Point beginPosition;
        private int delta;

        public bool IsSave;

        private Frame _frame;

        public Point Center;


        public Editor()
        {
            IsSave = true;
            _accessPhysicalObjects = new List<PhysObject>();
            _makedPhysicalObjects = new List<PhysObject>();
            _oldPositionMouse = Point.Empty;
            delta = 0;
            beginPosition = new Point(0, 50);
            _accessPhysicalObjects.AddRange(FileMapManager.LoadConfiguration());

            foreach (var accessPhysicalObject in _accessPhysicalObjects)
            {
                accessPhysicalObject.SetObjectSize(new Size(100, 70));
                accessPhysicalObject.SetObjectPosition(new Point(200, beginPosition.Y + 30 + delta));
                delta += 100;
            }
            delta = 100;
            int size = _accessPhysicalObjects.Count * delta;
            Center = Point.Empty;
            _frame = new Frame(new Size(300, size), beginPosition, delta);
        }

        public void OpenFile(string path)
        {
            _makedPhysicalObjects.Clear();
            LastMovingGameObject = null;
            _makedPhysicalObjects.AddRange(FileMapManager.LoadPhysicalObjects(path));
        }

        public void Close()
        {
        }

        public void SaveFile()
        {
            FileMapManager.SavePhysicalObjectsToFile(_makedPhysicalObjects);
            IsSave = true;
        }

        public void SaveAs(string path)
        {
            FileMapManager.SavePhysicalObjectsToFile(_makedPhysicalObjects, path);
            IsSave = true;
        }

        public void ShowScrollAccessGameObjects(Graphics device, Button button)
        {
            int positionY = beginPosition.Y;

            _frame.PaintFrame(device);
            for (int i = 0; i < _accessPhysicalObjects.Count; i++)
            {
                if (CurrentPhysicalObject == _accessPhysicalObjects[i])
                {
                    ShowGameObject(device, _accessPhysicalObjects[i], new Point(beginPosition.X, positionY));


                    Pen pen = new Pen(Color.LightGray, 5);
                    device.DrawRectangle(pen, beginPosition.X, positionY, 300, delta);
                    ShowChoose(button, new Point(beginPosition.X, positionY + delta / 2));
                }
                else
                {
                    ShowGameObject(device, _accessPhysicalObjects[i], new Point(beginPosition.X, positionY));
                }
                positionY += delta;
            }
        }

        public void ShowGameObject(Graphics device, PhysObject physicalObject, Point position)
        {
            Font font = new Font("Arial", 15);
            device.DrawString(physicalObject.ToString(), font, Brushes.Black, position);
            physicalObject.Draw(device);
        }

        public void ShowMakedGameObjects(Graphics device)
        {
            foreach (var makedPhysicalObject in _makedPhysicalObjects)
            {
                //makedPhysicalObject.Draw(device);
                //if (makedPhysicalObject != MovingPhysicalObject)
                Point oldPositon = makedPhysicalObject.GetObjectPosition();
                makedPhysicalObject.SetObjectPosition(new Point(Center.X + oldPositon.X,
                                                           Center.Y + oldPositon.Y));
                makedPhysicalObject.Draw(device);
                makedPhysicalObject.SetObjectPosition(oldPositon);
            }
        }

        public void ShowCurrentGameObject(Graphics device)
        {
            //if (CurrentPhysicalObject != null)
            //    device.draw
        }

        public void MakeGameObject()
        {
            _makedPhysicalObjects.Add(CurrentPhysicalObject);
        }

        public void ShowChoose(Button button, Point location)
        {
            if (CurrentPhysicalObject != null)
                button.Location = location;
        }

        public void AcceptChoose()
        {
            ChoosePhysicalObject = CurrentPhysicalObject;
            LastMovingGameObject = MovingPhysicalObject = CreateCopy(ChoosePhysicalObject);
        }

        private PhysObject CreateCopy(PhysObject physObject)
        {
            Type type = physObject.GetType();
            ConstructorInfo constructorInfo = type.GetConstructor(new Type[]{typeof(string), typeof(Point), typeof(Size), typeof(Image)});
            return (PhysObject)constructorInfo.Invoke(new object[]{physObject.GetObjectName(), physObject.GetObjectPosition(), physObject.GetObjectSize(), physObject.GetObjectTexture()});
        }

        public void ShowMovingGameObject(Graphics device)
        {
            if (MovingPhysicalObject != null && !_makedPhysicalObjects.Contains(MovingPhysicalObject))
                MovingPhysicalObject.Draw(device);
        }

        public void MoveChooseGameObject(Point locationMouse)
        {
            if (MovingPhysicalObject != null && ChoosePhysicalObject == null)
            {
                oldPositionMovingGameObject = MovingPhysicalObject.GetObjectPosition();
                MovingPhysicalObject.SetObjectPosition(new Point(MovingPhysicalObject.GetObjectPosition().X - (_oldPositionMouse.X - locationMouse.X),
                        MovingPhysicalObject.GetObjectPosition().Y - (_oldPositionMouse.Y - locationMouse.Y)));
                _oldPositionMouse = locationMouse;
                IsSave = false;
            }
            else
                if (MovingPhysicalObject != null && ChoosePhysicalObject != null)
                {
                    oldPositionMovingGameObject = MovingPhysicalObject.GetObjectPosition();
                    MovingPhysicalObject.SetObjectPosition(locationMouse);
                    IsSave = false;
                }

        }

        public bool IsChangeInfo()
        {
            if (MovingPhysicalObject != null)
            {
                if (oldPositionMovingGameObject.X != MovingPhysicalObject.GetObjectPosition().X)
                    return true;
                if (oldPositionMovingGameObject.Y != MovingPhysicalObject.GetObjectPosition().Y)
                    return true;
            }
            return false;
        }


        public bool PlaceMovingGameObject()
        {
            if (MovingPhysicalObject != null)
            {
                if (!_makedPhysicalObjects.Contains(MovingPhysicalObject))
                {
                    _makedPhysicalObjects.Add(MovingPhysicalObject);
                    MovingPhysicalObject.SetObjectPosition(
                        new Point(MovingPhysicalObject.GetObjectPosition().X - Center.X,
                            MovingPhysicalObject.GetObjectPosition().Y - Center.Y));

                }
                else
                {

                }
                LastMovingGameObject = MovingPhysicalObject;
                MovingPhysicalObject = null;
                return true;
            }
            return false;

        }

        public bool CancelChoose()
        {
            if (MovingPhysicalObject != null)
            {
                _makedPhysicalObjects.Remove(MovingPhysicalObject);
                LastMovingGameObject = MovingPhysicalObject = null;
                if (_makedPhysicalObjects.Count > 0)
                {
                    LastMovingGameObject = _makedPhysicalObjects.Last();
                }
                return true;
            }
            return false;
        }

        public void MarkGameObject(Point positionClick)
        {
            int index = _frame.ClickOnFrame(positionClick);
            if (index != -1 && index < _accessPhysicalObjects.Count)
            {
                CurrentPhysicalObject = _accessPhysicalObjects[index];
                indexCurrentPhysicalObject = index;
            }
        }

        public void CheckClick(Point locationClick)
        {
            foreach (var makedPhysicalObject in _makedPhysicalObjects)
            {
                if (Center.X + makedPhysicalObject.GetObjectPosition().X <= locationClick.X &&
                    locationClick.X <= Center.X + makedPhysicalObject.GetObjectPosition().X + makedPhysicalObject.GetObjectSize().Width)
                    if (Center.Y + makedPhysicalObject.GetObjectPosition().Y <= locationClick.Y &&
                        locationClick.Y <=
                        Center.Y + makedPhysicalObject.GetObjectPosition().Y + makedPhysicalObject.GetObjectSize().Height)
                    {
                        LastMovingGameObject = MovingPhysicalObject = makedPhysicalObject;
                        ChoosePhysicalObject = null;
                    }
            }
        }

        public void HighLightLastMovingGameObject(Graphics device)
        {
            if (LastMovingGameObject != null)
            {
                //if (LastMovingGameObject == MovingPhysicalObject)
                //    device.DrawRectangle(Pens.Red, LastMovingGameObject.Position.X, LastMovingGameObject.Position.Y,
                //        LastMovingGameObject.size.Width, LastMovingGameObject.size.Height);
                //else
                //{
                //    device.DrawRectangle(Pens.Red, axis.Center.X + LastMovingGameObject.Position.X, axis.Center.Y + LastMovingGameObject.Position.Y,
                //        LastMovingGameObject.size.Width, LastMovingGameObject.size.Height);
                //}
            }
        }
    }
}
